﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.Collections.Generic;

namespace CommonUtility
{
    public class Gb2312Encoding
    {
        /// <summary>
        /// 将字符串转为gb2312编码的字节数组
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>gb2312字节数组</returns>
        public static byte[] GetBytes(string str)
        {
            byte[] b = null;
            List<byte> list = new List<byte>();
            foreach (char c in str.ToCharArray())
            {
                if (UnicodeToGb2312Dictonary.TryGetBytes(c, out b))
                {
                    list.AddRange(b);
                }
                else
                {
                    list.Add(Encoding.UTF8.GetBytes(new char[] { c })[0]);
                }
            }

            return list.ToArray();
        }

        /// <summary>
        /// 将gb2312编码的字节数组转化为字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string GetString(byte[] bytes)
        {
            char c;
            List<char> list = new List<char>();
            for (int i = 0; i < bytes.Length; i += 2)
            {
                if (i + 1 >= bytes.Length)
                {
                    char[] last = Encoding.UTF8.GetChars(new byte[] { bytes[i] });
                    list.Add(last[0]);
                }
                else
                {
                    byte[] bb = new byte[] { bytes[i], bytes[i + 1] };
                    if (Gb2312toUnicodeDictinary.TryGetChar(bb, out c))
                    {
                        list.Add(c);
                    }
                    else
                    {
                        char[] tt = Encoding.UTF8.GetChars(new byte[] { bb[1] });
                        list.Add(tt[0]);
                        if (i + 2 >= bytes.Length)
                        {
                            char[] tttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
                            list.Add(tttt[0]);
                        }
                        else
                        {
                            byte[] test = new byte[] { bb[0], bytes[i + 2] };
                            if (Gb2312toUnicodeDictinary.TryGetChar(test, out c))
                            {
                                list.Add(c);
                                i++;
                            }
                            else
                            {
                                char[] ttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
                                list.Add(ttt[0]);
                            }

                        }
                    }
                }
            }

            return new string(list.ToArray());
        }
    }

    internal static class Gb2312toUnicodeDictinary
    {
        public static bool TryGetChar(byte[] b, out char gbchar)
        {
            if (b.Length > 2)
                throw new ArgumentOutOfRangeException();
            byte t = b[0];
            b[0] = b[1];
            b[1] = t;
            UInt16 key = (UInt16)(BitConverter.ToUInt16(b, 0) - 0x8080);
            UInt16 value;
            if (Gb2312AndUnicodeDic.gb2312toUnicode.TryGetValue(key, out value))
            {
                gbchar = Encoding.Unicode.GetChars(BitConverter.GetBytes(value))[0];
                return true;
            }
            else
            {
                gbchar = 'e';
                return false;
            }
        }
    }

    internal static class UnicodeToGb2312Dictonary
    {
        public static readonly int Count = 7426;

        public static bool TryGetBytes(char unichar, out byte[] b)
        {
            b = new byte[2];
            ushort key = (ushort)unichar;
            ushort value;
            if (Gb2312AndUnicodeDic.unicodeToGb2312.TryGetValue(key, out value))
            {
                byte[] bGet = BitConverter.GetBytes(value + 0x8080);
                b[0] = bGet[1];
                b[1] = bGet[0];
                return true;
            }

            return false;
        }
    }
}
